import socket,select,os
from helpFunc import *
from connbase import *
import hashlib

class tcpRe(tcpReBase):
    def __init__(self):    
        tcpReBase.__init__(self)        
        self.accepSock = s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)     
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(('0.0.0.0',con_localPort))
        s.listen(con_maxConn)
        self.staTime = time.monotonic()
        self.connSock = s = socket.socket()
        add = (serverIp,server_port)
        s.connect(add)
        self.connSock.setblocking(False)
        
        while True:
            self.dowork()
    
    def dealAcc(self):
        csock, caddr = self.accepSock.accept()
        self.connNum += 1
        if self.connNum>self.maxNum:
            csock.close()
            self.connNum -= 1
            print ('too much',self.connNum)
        else:
            id = hashlib.md5(str(uuid.uuid1()).encode()).digest()
            msg = self.makeMsg(askConn_g,id,b'1')                
            print ("ask conn",self.connNum)
            csock.setblocking(0)
            self.idMap[id] = {'sock':csock}
            self.sendMsg(msg)
            
    def dealConnSock(self):
        ss = self.connSock.recv(tcpReadLen)   
        self.recvLen += len(ss)
        msgList = self.dealData( ss)
        for one in msgList:
            ty,id,da = self.decodeMsg(one)
            re = da[0]
            if  ty==ping_g:
                print('ping back')
            if  ty==connBack_g:
                if re:
                    self.proxySocks[self.idMap[id]['sock']] = {'id':id,'data':b'','peerclose':False,
                                                               'peerFull':False,'tellMyFull':False}
                    print ('askConnBack ok')
                    continue
                self.idMap[id]['sock'].close()
                del self.idMap[id]
                self.connNum -= 1                        
                print ('conn close',self.connNum)
                continue
            self.dealConnsockNormal(id,ty,da)
     
    def dowork(self):   
        self.doPeriod()
        if time.monotonic()-self.staTime>10:
            self.staTime = time.monotonic()
            msg = self.makeMsg(ping_g,b'1'*16,b's')                
            self.sendMsg(msg)    
            
        rl = [self.accepSock,self.connSock]
        if len(self.peerBuf)<con_connBufSize:
            rl += self.getReadSocks()
     
        wl = self.getWriteSocks()
        if self.peerBuf:
            wl.append(self.connSock)
        
        el = []
        rl,wl,el = select.select(rl,wl,el,1)        
        for sock in rl:                                                         
            if  sock == self.accepSock:
                self.dealAcc()
            elif sock == self.connSock:
                self.dealConnSock()
            else:
                self.dealProxysocks(sock)
        for sock in wl:
            if sock == self.connSock:
                n = self.connSock.send(self.peerBuf)
                self.sendLen += n
                self.peerBuf = self.peerBuf[n:]
                continue
            self.dealWritesocks(sock)
            
if __name__ == '__main__':
    tcpRe()